#include <iostream>
#include <string>
#include <map>
#include <ctime>

template <typename T>
void Print(const T &v)
{
    for (auto ite = v.begin(); ite != v.end(); ite++)
    {
        std::cout << *ite << " ";
    }
    std::cout << std::endl;
}

int main()
{
#if 0
    // 键值对
    std::pair<int, std::string> p = {1, "zhangsan"};
    std::cout << p.first << " " << p.second << std::endl;
#endif

#if 0
    // 模板函数
    std::pair<int, std::string> p = std::make_pair<int, std::string>(1, "zhangsan");
    // std::pair<int, std::string> p = std::make_pair(1, "zhangsan"); // 可以隐式转换模板
    // auto p = std::make_pair(1, std::string("zhangsan")); // 自动类型推导，类型必须严格匹配（要写清楚"zhangsan"是什么类型的）
    std::cout << p.first << " " << p.second << std::endl;
#endif

#if 0
    // map容器：它是键值对的集合，根据键值对的first来进行排序
    std::map<int, std::string> m;
    // 三种插入方式
    // map容器的键唯一，不允许出现重复
    m.insert({1, "zhangsan"});
    m.insert(std::make_pair(3, "lisi"));
    m.insert(std::pair<int, std::string>(2, "wangwu"));
    // m.insert_or_assign 不存在就插入，存在就覆盖

    // 插入（存在则修改，不存在就新增）
    m[4] = "zhaoliu"; // []重载

    for (auto ite = m.begin(); ite != m.end(); ite++)
    {
        std::cout << ite->first << " " << ite->second << std::endl;
    }
    std::cout << std::endl;

    // 查找
    auto ite = m.find(2);
    if (ite == m.end())
    {
        std::cout << "没找到" << std::endl;
    }
    else
    {
        std::cout << ite->second << std::endl;
    }
    std::cout << std::endl;

    // 删除
    m.erase(1);
    // m.erase(m.find(1)); // 根据迭代器去删也可以，删的就是迭代器

    for (auto ite = m.begin(); ite != m.end(); ite++)
    {
        std::cout << ite->first << " " << ite->second << std::endl;
    }
    std::cout << std::endl;

    // 从容器中提取元素：
    // 将指定的元素从容器中取出并返回，同时容器中不再包含该元素，容器大小因此减小
    // 被提取的元素通常会从容器中移除，但还可以在提取后继续使用（以返回值的形式存在）
    // 在树中，取的是节点，而不仅仅是值（节点包含了元素的值和其在容器中的位置和其他属性）
    auto node = m.extract(3);
    // m.insert(std::move(node));
    for (auto ite = m.begin(); ite != m.end(); ite++)
    {
        std::cout << ite->first << " " << ite->second << std::endl;
    }
#endif

#if 1
    // 用map容器解决一个问题

    // 生成100个1~10以内的随机数
    srand(time(nullptr));
    int a[100];
    for (int i = 0; i < 100; i++)
    {
        a[i] = rand() % 10 + 1;
        std::cout << a[i] << " ";
    }
    std::cout << std::endl;

    // 求出现次数最多的数，输出它的值和下标
    std::map<int, int> m; // 定义一个map容器，第一个int代表值，第二个int代表它出现的次数
    for (int i = 0; i < 100; i++)
    {
        // 这里m[a[i]]是用来访问map中的键为a[i]的元素
        // 如果a[i]在map中存在，返回它对应的值（出现的次数）
        // 如果不存在，则会自动插入这个键，并将值初始化为0
        m[a[i]]++;
    }
    auto MaxIte = m.begin();
    for (auto ite = m.begin(); ite != m.end(); ite++)
    {
        if (ite->second > MaxIte->second)
            MaxIte = ite;
        std::cout << ite->first << " " << ite->second << std::endl;
    }
    std::cout << "出现次数最多的数是:" << MaxIte->first << " 出现了" << MaxIte->second << "次" << std::endl;
#endif

    return 0;
}